package heap

// instanceof
// checkcast
func (self *Klass) IsAssignableFrom(other *Klass) bool {
	// self 和 other 是同一个地址 即同一个类
	if self == other {
		return true
	}
	//如果 self 是数组
	if self.IsArray() {
		//如果 self 是数组   other 也是数组 // 比较他们的元素的类是否相同
		if other.IsArray() {
			sc := self.ComponentClass()
			tc := other.ComponentClass()
			return sc == tc || tc.IsAssignableFrom(sc)
		} else {
			// 如果self 是数组  other 不是数组  那么 other 是 java.lang.Object 要么实现了接口 java/lang/Cloneable|java/io/Serializable
			// 1. 判断 other 是否是接口
			// 1.1  other 是接口  other 是否是clone和serialize接口 如果是  则返回true 因为所有的类都实现了这两个接口
			// 这时有几个歪瓜就会说啦 如果是其他接口就要一概否定吗  我的回答是的 就是一棍子打死
			// 1.2 other 不是接口   判断other 是否是java.lang.Object 如果是  则返回true 因为所有的类继承了这个类
			if other.IsInterface() {
				return other.isJlCloneable() || other.isJioSerializable()
			} else {
				return other.isJlObject()
			}
		}
	} else {
		// 如果 self 是接口   other 也是接口   self extents  other
		// 如果 self 是接口   other 是类     other 必须是java.lang.Object
		if self.IsInterface() {
			if other.IsInterface() {
				return other.isSuperInterfaceOf(self)
			} else {
				return other.isJlObject()
			}
		} else {
			//如果 self 是类  other 是接口  self implements other
			//如果 self 是类  other 是类    self extends other
			if other.IsInterface() {
				return self.IsImplements(other)
			} else {
				return self.IsSubClassOf(other)
			}
		}
	}

	return false
}

// iface extends k
func (superInterface *Klass) isSuperInterfaceOf(subClass *Klass) bool {
	return subClass.isSubInterfaceOf(superInterface)
}

// k extends iface
func (k *Klass) isSubInterfaceOf(iface *Klass) bool {
	for _, superInterface := range k.interfaces {
		if superInterface == iface || superInterface.isSubInterfaceOf(iface) {
			return true
		}
	}
	return false
}

// k implements iface
func (k *Klass) IsImplements(iface *Klass) bool {
	for c := k; c != nil; c = c.superClass {
		for _, i := range c.interfaces {
			if i == iface || i.isSubInterfaceOf(iface) {
				return true
			}
		}
	}
	return false
}

// k extends c
func (k *Klass) IsSubClassOf(other *Klass) bool {
	for c := k.superClass; c != nil; c = c.superClass {
		if c == other {
			return true
		}
	}
	return false
}
